package com.cloudcentral.controller;

import com.alibaba.fastjson.JSON;
import com.cloudcentral.exception.FailureException;
import com.cloudcentral.util.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;

import static com.cloudcentral.util.Utils.errorMessage;

/**
 * Create by Administrator
 * 2023/11/9 16:39
 */
@Slf4j
@RestController
@RequestMapping("/authorization")
@Tag(name = "认证授权")
public class AuthorizationController extends BaseController {
  private final RestTemplate restTemplate;
  @Value("${server.port}")
  private String serverPort;

  @Autowired
  public AuthorizationController(RestTemplate restTemplate) {
    this.restTemplate = restTemplate;
  }

  @PostMapping("/logout")
  @Operation(summary = "注销登录")
  public Result<Boolean> logout(@RequestParam("access_token") String accessToken,
                                @RequestParam("refresh_token") String refreshToken) throws FailureException {
    if (StringUtils.isBlank(accessToken)) throw new FailureException("缺少令牌");
    else if (StringUtils.isBlank(refreshToken)) throw new FailureException("缺少刷新令牌");
    else {
      HttpHeaders headers = new HttpHeaders();
      headers.setBasicAuth("cloudcentral", "cloudcentral", StandardCharsets.UTF_8);
      headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
      try {
        String ip = InetAddress.getLocalHost().getHostAddress();
        String uri = StringUtils.join("http://", ip, ":", serverPort, "/oauth2/revoke");
        MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
        formData.add("token", accessToken);
        formData.add("token_type_hint", "access_token");
        restTemplate.exchange(uri, HttpMethod.POST, new HttpEntity<>(formData, headers), String.class);
        formData.clear();
        formData.add("token", refreshToken);
        formData.add("token_type_hint", "refresh_token");
        restTemplate.exchange(uri, HttpMethod.POST, new HttpEntity<>(formData, headers), String.class);
        return Result.ok();
      } catch (Exception e) {
        return Result.fail(errorMessage(e));
      }
    }
  }

  @GetMapping("/token")
  @Operation(summary = "获取token")
  public Result<Object> token(HttpServletRequest request) {
    HttpHeaders headers = new HttpHeaders();
    headers.setBasicAuth("cloudcentral", "cloudcentral", StandardCharsets.UTF_8);
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    String cookie = request.getHeader("Cookie");
    if (StringUtils.isNotBlank(cookie)) headers.set("Cookie", cookie);
    MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
    Iterator<String> iterator = request.getParameterNames().asIterator();
    while (iterator.hasNext()) {
      String key = iterator.next();
      formData.add(key, request.getParameter(key));
    }
    try {
      String ip = InetAddress.getLocalHost().getHostAddress();
      String uri = StringUtils.join("http://", ip, ":", serverPort, "/oauth2/token");
      HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(formData, headers);
      ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.POST, httpEntity, String.class);
      String data = response.getBody();
      return StringUtils.isBlank(data) ? Result.ok() : Result.ok(JSON.parseObject(data, Object.class));
    } catch (Exception e) {
      return Result.fail(errorMessage(e));
    }
  }

  @GetMapping("/userinfo")
  @Operation(summary = "用户信息")
  public Object userinfo(HttpServletRequest request) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    String authorization = request.getHeader("Authorization");
    headers.set("Authorization", StringUtils.isBlank(authorization) ? OAuth2AccessToken.TokenType.BEARER.getValue() : authorization);
    try {
      String ip = InetAddress.getLocalHost().getHostAddress();
      String uri = StringUtils.join("http://", ip, ":", serverPort, "/oauth2/userinfo");
      HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(headers);
      ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, httpEntity, String.class);
      return JSON.parseObject(response.getBody(), Object.class);
    } catch (Exception e) {
      return Result.fail(errorMessage(e));
    }
  }
}
